﻿using System.Collections.Generic;
namespace RobotGerchik.DataClass
{
    public class TransaqCommands
    {

        #region Работа с сервером
        /// <summary>
        /// Разорвать соединение
        /// Результатом является структура server_status.
        /// В случае возникновения ошибок, приводящих к завершению подключения к
        /// серверу (приходит структура <server_status connected="false"/>), вызов
        /// команды disconnect перед командой connect не требуется.
        /// </summary>
        public string Disconnect()
        {
            return "<command id=\"disconnect\"/>";
        }

        /// <summary>
        /// Получить текущее состояние соединения с сервером.
        /// Результатом является структура "server_status" и "overnight status".
        /// </summary>
        public string ServerStatus()
        {
            return "<command id=\"server_status\"/>";
        } 

        /// <summary>
        /// Получить разницу между временем на компьютере пользователя и серверным
        /// </summary>
        public string GetServtimeDifference()
        {
            return "<command id=\"get_servtime_difference\"/>";
        } 


        #endregion

        #region Подписка на получение данных
        /// <summary>
        /// Подписаться на получение котировок
        /// </summary>
        /// <param name="secid">идентификатор бумаг</param>
        /// <returns></returns>
        public string SubscribeQuotations(int secid)
        {
            string cmd = "<command id=\"subscribe\">";
            cmd = cmd + "<quotations>";
            cmd = cmd + "<secid>" + secid + "</secid>";
            cmd = cmd + "</quotations>";
            cmd = cmd + "</command>";

            return cmd;
        }

        /// <summary>
        /// Подписаться на получение котировок с использованием элемента security для идентификации бумаг
        /// </summary>
        /// <param name="board">идентификатор режима торгов</param>
        /// <param name="seccode">код инструмента</param>
        /// <returns>Результатом работы является начало передач всех изменений по заданным бумагам</returns>
        public string SubscribeQuotationsBoardSeccode(string board, string seccode)
        {
            string cmd = "<command id=\"subscribe\">";
            cmd = cmd + "<quotations>";
            cmd = cmd + "<security>";
            cmd = cmd + "<board>" + board + "</board>";
            cmd = cmd + "<seccode>" + seccode + "</seccode>";
            cmd = cmd + "</security>";
            cmd = cmd + "</quotations>";
            cmd = cmd + "</command>";

            return cmd;
        }

        /// <summary>
        /// Подписаться на получение сделок
        /// </summary>
        /// <param name="secid">идентификатор бумаг</param>
        /// <returns></returns>
        public string SubscribeAllTrades(int secid)
        {
            string cmd = "<command id=\"subscribe\">";
            cmd = cmd + "<alltrades>";
            cmd = cmd + "<secid>" + secid + "</secid>";
            cmd = cmd + "</alltrades>";
            cmd = cmd + "</command>";

            return cmd;
        }

        /// <summary>
        /// Подписаться на получение всех сделок с использованием элемента security для идентификации бумаг
        /// </summary>
        /// <param name="board">идентификатор режима торгов</param>
        /// <param name="seccode">код инструмента</param>
        /// <returns>Результатом работы является начало передач всех изменений по заданным бумагам</returns>
        public string SubscribeAllTradesBoardSeccode(string board, string seccode)
        {
            string cmd = "<command id=\"subscribe\">";
            cmd = cmd + "<alltrades>";
            cmd = cmd + "<security>";
            cmd = cmd + "<board>" + board + "</board>";
            cmd = cmd + "<seccode>" + seccode + "</seccode>";
            cmd = cmd + "</security>";
            cmd = cmd + "</alltrades>";
            cmd = cmd + "</command>";

            return cmd;
        }

        /// <summary>
        /// Подписаться на получение глубины рынка (стакана)
        /// </summary>
        /// <param name="secid">идентификатор бумаг</param>
        /// <returns></returns>
        public string SubscribeQuotes(int secid)
        {
            string cmd = "<command id=\"subscribe\">";
            cmd = cmd + "<quotes>";
            cmd = cmd + "<secid>" + secid + "</secid>";
            cmd = cmd + "</quotes>";
            cmd = cmd + "</command>";

            return cmd;
        }

        /// <summary>
        /// Подписаться на изменение "стакана" с использованием элемента security для идентификации бумаг
        /// </summary>
        /// <param name="board">идентификатор режима торгов</param>
        /// <param name="seccode">код инструмента</param>
        /// <returns>Результатом работы является начало передач всех изменений по заданным бумагам</returns>
        public string SubscribeQuotesBoardSeccode(string board, string seccode)
        {
            string cmd = "<command id=\"subscribe\">";
            cmd = cmd + "<quote>";
            cmd = cmd + "<security>";
            cmd = cmd + "<board>" + board + "</board>";
            cmd = cmd + "<seccode>" + seccode + "</seccode>";
            cmd = cmd + "</security>";
            cmd = cmd + "</quote>";
            cmd = cmd + "</command>";

            return cmd;
        }

        /// <summary>
        /// Подписка на тики бумаг
        /// </summary>
        /// <param name="list">Список инструментов</param>
        /// <returns>Тики выдаются в хронологическом порядке вперемешку по инструментам</returns>
        public string SubscribeTick(List<int> list)
        {
            string cmd = "<command id=\"subscribe_ticks\" filter=\"true\">";
            for (int i = 0; i < list.Count; i++)
            {
                cmd = cmd + "<security secid=\"" + list[i]   +"\" tradeno=\"0\"/>";    
            }
            cmd = cmd + "</command>";

            return cmd;
        }

        #endregion

        #region Отписка на получение данных
        /// <summary>
        /// Отписаться на получение котировок
        /// </summary>
        /// <param name="secid">идентификатор бумаг</param>
        /// <returns></returns>
        public string UnsubscribeQuotations(int secid)
        {
            string cmd = "<command id=\"unsubscribe\">";
            cmd = cmd + "<quotations>";
            cmd = cmd + "<secid>" + secid + "</secid>";
            cmd = cmd + "</quotations>";
            cmd = cmd + "</command>";

            return cmd;
        }

        /// <summary>
        /// Отписаться на получение котировок с использованием элемента security для идентификации бумаг
        /// </summary>
        /// <param name="board">идентификатор режима торгов</param>
        /// <param name="seccode">код инструмента</param>
        /// <returns>Результатом работы является прекращение передач всех изменений по заданным бумагам</returns>
        public string UnsubscribeQuotationsBoardSeccode(string board, string seccode)
        {
            string cmd = "<command id=\"unsubscribe\">";
            cmd = cmd + "<quotations>";
            cmd = cmd + "<security>";
            cmd = cmd + "<board>" + board + "</board>";
            cmd = cmd + "<seccode>" + seccode + "</seccode>";
            cmd = cmd + "</security>";
            cmd = cmd + "</quotations>";
            cmd = cmd + "</command>";

            return cmd;
        }

        /// <summary>
        /// Отписаться на получение сделок
        /// </summary>
        /// <param name="secid">идентификатор бумаг</param>
        /// <returns></returns>
        public string UnsubscribeAllTrades(int secid)
        {
            string cmd = "<command id=\"unsubscribe\">";
            cmd = cmd + "<alltrades>";
            cmd = cmd + "<secid>" + secid + "</secid>";
            cmd = cmd + "</alltrades>";
            cmd = cmd + "</command>";

            return cmd;
        }

        /// <summary>
        /// Отписаться на получение всех сделок с использованием элемента security для идентификации бумаг
        /// </summary>
        /// <param name="board">идентификатор режима торгов</param>
        /// <param name="seccode">код инструмента</param>
        /// <returns>Результатом работы является прекращение передач всех изменений по заданным бумагам</returns>
        public string UnsubscribeAllTradesBoardSeccode(string board, string seccode)
        {
            string cmd = "<command id=\"unsubscribe\">";
            cmd = cmd + "<alltrades>";
            cmd = cmd + "<security>";
            cmd = cmd + "<board>" + board + "</board>";
            cmd = cmd + "<seccode>" + seccode + "</seccode>";
            cmd = cmd + "</security>";
            cmd = cmd + "</alltrades>";
            cmd = cmd + "</command>";

            return cmd;
        }

        /// <summary>
        /// Отписаться на получение глубины рынка (стакана)
        /// </summary>
        /// <param name="secid">идентификатор бумаг</param>
        /// <returns></returns>
        public string UnsubscribeQuotes(int secid)
        {
            string cmd = "<command id=\"unsubscribe\">";
            cmd = cmd + "<quotes>";
            cmd = cmd + "<secid>" + secid + "</secid>";
            cmd = cmd + "</quotes>";
            cmd = cmd + "</command>";

            return cmd;
        }

        /// <summary>
        /// Отписаться на изменение "стакана" с использованием элемента security для идентификации бумаг
        /// </summary>
        /// <param name="board">идентификатор режима торгов</param>
        /// <param name="seccode">код инструмента</param>
        /// <returns>Результатом работы является прекращение передач всех изменений по заданным бумагам</returns>
        public string UnsubscribeQuotesBoardSeccode(string board, string seccode)
        {
            string cmd = "<command id=\"unsubscribe\">";
            cmd = cmd + "<quote>";
            cmd = cmd + "<security>";
            cmd = cmd + "<board>" + board + "</board>";
            cmd = cmd + "<seccode>" + seccode + "</seccode>";
            cmd = cmd + "</security>";
            cmd = cmd + "</quote>";
            cmd = cmd + "</command>";

            return cmd;
        }
        #endregion

        #region Получение исторических данных

        /// <summary>
        /// Выдать последние N свечей заданного периода, по заданному инструменту
        /// </summary>
        /// <param name="secid"></param>
        /// <param name="timeframe">идентификатор периода</param>
        /// <param name="countCandle">количество свечей</param>
        /// <param name="flag">true/false</param>
        /// <returns>Результатом работы является структура вида candles.</returns>
        /// Параметр reset="true" говорит, что нужно выдавать самые свежие данные, в
        /// противном случае будут выданы свечи в продолжение предыдущего запроса.
        public string GetHistoryDate(int secid, int timeframe, int countCandle, string flag)
        {
            string cmd = "<command id=\"gethistorydata\"";
            cmd = cmd + " secid=" + secid;
            cmd = cmd + " period=" + timeframe;
            cmd = cmd + " count=" + countCandle;
            cmd = cmd + " reset=" + flag + " />";

            return cmd;
        }

        /// <summary>
        /// Выдать последние N свечей заданного периода, по заданному инструменту
        /// </summary>
        /// <param name="board">идентификатор режима торгов</param>
        /// <param name="seccode">код инструмента</param>
        /// <param name="timeframe">идентификатор периода</param>
        /// <param name="countCandle">количество свечей</param>
        /// <param name="flag">true/false</param>
        /// <returns>Результатом работы является структура вида candles.</returns>
        /// Параметр reset="true" говорит, что нужно выдавать самые свежие данные, в
        /// противном случае будут выданы свечи в продолжение предыдущего запроса.
        public string GetHistoryDateBoardSeccode(string board, string seccode, int timeframe, int countCandle, string flag)
        {
            string cmd = "<command id=\"gethistorydata\">";
            cmd = cmd + "<security>";
            cmd = cmd + "<board>" + board + "</board>";
            cmd = cmd + "<seccode>" + seccode + "</seccode>";
            cmd = cmd + "</security>";
            cmd = cmd + "<period>" + timeframe + "</period>";
            cmd = cmd + "<count>" + countCandle + "</count>";
            cmd = cmd + "<reset>" + flag + "</reset>";
            cmd = cmd + "</command>";

            return cmd;
        }

        #endregion

        #region Заявки

        /// <summary>
        /// Возможность отправки рыночной заявки по по конкретному инструменту
        /// Приходит в случае, если во время работы Коннектора изменится
        /// возможность выставления или снятия рыночной заявки по инструменту с
        /// идентификатором id.
        /// </summary>
        /// <param name="secid">код инструмента</param>
        /// <param name="seccode">инструмента</param>
        /// <param name="permit">"yes/no"</param>
        /// <returns></returns>
        public string MakeOrderToMarket(int secid, string seccode, string permit)
        {
            return "<marketord secid=\""+ secid + "\" seccode=\"" + seccode + "\" premit=\"" + permit +"\"/>";
        } 

        ///// <summary>
        ///// Подать новую заявку на биржу (secid)
        ///// </summary>
        ///// <param name="marketOrLimit">рыночная (true) или лимтная (false)</param>
        ///// <param name="useCredit">использовать заемные деньги</param>
        ///// <param name="secid">идентификатор бумаги</param>
        ///// Для идентификации инструмента необходимо задать secid или элемент security. Если заданы оба, то используется security.
        ///// <param name="board">идентификатор режима торгов</param>
        ///// <param name="seccode">код инструмента</param>
        ///// <param name="client">клиент</param>
        ///// <param name="price">цена</param>
        ///// 
        ///// <param name="quantity">количество в лотах</param>
        ///// <param name="oper">("В" - покупка, или "S" – продажа)</param>
        ///// <param name="flag">комментарий, есть ограничения</param>
        ///// <returns>id</returns>
        ///// Немедленным результатом запроса neworder будет структура result,
        ///// сообщающая о том, была ли принята заявка сервером TRANSAQ (не Биржей!)
        ///// В случае успеха результатом будет следующий тег:
        ///// result success="true" transactionid="id"
        ///// Только для FORTS. На рынке FORTS не доступны параметры usecredit и nosplit.
        //public string NewOrder(bool marketOrLimit, bool useCredit, int secid, string board, string seccode, string client, int quantity, double price, char oper, string flag)
        //{
        //    string cmd = "<command id=\"neworder\">";
        //    cmd = cmd + "<secid>" + secid + "</secid>";
        //    cmd = cmd + "<client>" + client + "</client>";
        //    if (!marketOrLimit)
        //        cmd = cmd + "<price>" + price + "</price>";
        //    //cmd = cmd + "<hidden>" + flag + "</hidden>"; //необязательное поле
        //    cmd = cmd + "<quantity>" + quantity + "</quantity>";
        //    cmd = cmd + "<buysell>" + oper + "</buysell>";
        //    if (marketOrLimit)
        //        cmd = cmd + "<bymarket/>";
        //    cmd = cmd + "<brokerref>" + flag + "</brokerref>";
        //    cmd = cmd + "<unfilled>" + "PutInQueue" + "</unfilled>";
        //    if (useCredit)
        //        cmd = cmd + "<usecredit/>";
        //    //cmd = cmd + "<nosplit/>"; //Не ясно нужно использовать или нет
        //    cmd = cmd + "</command>";

        //    return cmd;
        //}

        /// <summary>
        /// Подать новую заявку на биржу (Board и Seccode)
        /// </summary>
        /// <param name="marketOrLimit">рыночная (true) или лимтная (false)</param>
        /// <param name="useCredit">использовать заемные деньги</param>
        /// <param name="secid">идентификатор бумаги</param>
        /// Для идентификации инструмента необходимо задать secid или элемент security. Если заданы оба, то используется security.
        /// <param name="board">идентификатор режима торгов</param>
        /// <param name="seccode">код инструмента</param>
        /// <param name="client">клиент</param>
        /// <param name="price">цена</param>
        /// 
        /// <param name="quantity">количество в лотах</param>
        /// <param name="oper">("В" - покупка, или "S" – продажа)</param>
        /// <param name="flag">комментарий, есть ограничения</param>
        /// <returns>id</returns>
        /// Немедленным результатом запроса neworder будет структура result,
        /// сообщающая о том, была ли принята заявка сервером TRANSAQ (не Биржей!)
        /// В случае успеха результатом будет следующий тег:
        /// result success="true" transactionid="id"
        /// Только для FORTS. На рынке FORTS не доступны параметры usecredit и nosplit.
        public string NewOrderBoardSeccode(bool marketOrLimit, bool useCredit, int secid, string board, string seccode, string client, int quantity, double price, char oper, string flag)
        {
            string cmd = "<command id=\"neworder\">";
            cmd = cmd + "<security>";
            cmd = cmd + "<board>" + board + "</board>";
            cmd = cmd + "<seccode>" + seccode + "</seccode>";
            cmd = cmd + "</security>";
            cmd = cmd + "<client>" + client + "</client>";
            if (!marketOrLimit)
                cmd = cmd + "<price>" + price.ToString().Replace(',','.') + "</price>";
            //cmd = cmd + "<hidden>" + flag + "</hidden>"; //необязательное поле
            cmd = cmd + "<quantity>" + quantity + "</quantity>";
            cmd = cmd + "<buysell>" + oper + "</buysell>";
            if (marketOrLimit)
                cmd = cmd + "<bymarket/>";
            cmd = cmd + "<brokerref>" + flag + "</brokerref>";
            cmd = cmd + "<unfilled>" + "PutInQueue" + "</unfilled>";
            if (useCredit)
                cmd = cmd + "<usecredit/>";
            //cmd = cmd + "<nosplit/>"; //Не ясно нужно использовать или нет
            cmd = cmd + "</command>";

            return cmd;
        }



        #endregion

        public string ReplaceChar(double price)
        {
            char PointChar = ',';
            string str = (1.2).ToString();
            if (str.IndexOf('.') > 0) PointChar = '.';

            if (PointChar == ',')
                return price.ToString().Replace('.', PointChar);

            if (PointChar == '.')
                return price.ToString().Replace(',', PointChar);

            return price.ToString();
        }

        #region Стоп-заявки

        /// <summary>
        /// Подать новую заявку на биржу (Board и Seccode)
        /// </summary>
        /// <param name="marketOrLimit">рыночная (true) или лимтная (false)</param>
        /// <param name="useCredit">использовать заемные деньги</param>
        /// <param name="secid">идентификатор бумаги</param>
        /// Для идентификации инструмента необходимо задать secid или элемент security. Если заданы оба, то используется security.
        /// <param name="board">идентификатор режима торгов</param>
        /// <param name="seccode">код инструмента</param>
        /// <param name="client">клиент</param>
        /// <param name="quantity">количество в лотах</param>
        /// <param name="oper">("В" - покупка, или "S" – продажа)</param>
        /// <param name="flag">комментарий, есть ограничения</param>
        /// <param name="priceActivationProfit"></param>
        /// <param name="priceOrder"></param>
        /// <param name="priceActivationStop"></param>
        /// <param name="priceOrderStop"></param>
        /// <returns>id</returns>
        /// Немедленным результатом запроса neworder будет структура result,
        /// сообщающая о том, была ли принята заявка сервером TRANSAQ (не Биржей!)
        /// В случае успеха результатом будет следующий тег:
        /// result success="true" transactionid="id"
        /// Только для FORTS. На рынке FORTS не доступны параметры usecredit и nosplit.
        public string NewStopOrderBoardSeccode(bool marketOrLimit, bool useCredit, int secid, string board, string seccode, string client, int quantity, char oper, string flag,
            double priceActivationStop, double priceOrderStop, double priceActivationProfit, double priceOrder, double spread)
        {
            string cmd = "<command id=\"newstoporder\">";
            cmd = cmd + "<security>";
            cmd = cmd + "<board>" + board + "</board>";
            cmd = cmd + "<seccode>" + seccode + "</seccode>";
            cmd = cmd + "</security>";
            cmd = cmd + "<client>" + client + "</client>";
            cmd = cmd + "<buysell>" + oper + "</buysell>";
            cmd = cmd + "<linkedorderno></linkedorderno>";
            cmd = cmd + "<stoploss>";
            cmd = cmd + "<activationprice>" + priceActivationStop.ToString().Replace(',','.') + "</activationprice>";
            cmd = cmd + "<orderprice>" + priceOrderStop.ToString().Replace(',', '.') + "</orderprice>";
            if (marketOrLimit)
            cmd = cmd + "<bymarket/>";
            cmd = cmd + "<quantity>" + quantity + "</quantity>";
            cmd = cmd + "</stoploss>";

            cmd = cmd + "<takeprofit>";
            cmd = cmd + "<activationprice>" + priceActivationProfit.ToString().Replace(',', '.') + "</activationprice>";
            cmd = cmd + "<quantity>" + quantity + "</quantity>";
            cmd = cmd + "<correction>" + priceOrder.ToString().Replace(',', '.') + "</correction>";
            cmd = cmd + "<spread>" + spread.ToString().Replace(',', '.') + "</spread>";
            if (marketOrLimit)
                cmd = cmd + "<bymarket/>";
            cmd = cmd + "</takeprofit>";

            cmd = cmd + "</command>";

            return cmd;
        }

        #endregion

        #region Снятие заявок и стоп-заявок и перестановка

        /// <summary>
        /// Отменить заявку
        /// </summary>
        /// <param name="id"></param>
        /// <returns>Результатом работы является отмена (снятие) заявки. Если произойдут какие-либо ошибки (заявка уже исполнена, уже снята, некорректный номер и т. д.), об этом будет сообщено в возвращаемом теге result</returns>
        public string CancelOrder(int id)
        {
            string cmd = "<command id=\"cancelorder\">";
            cmd = cmd + "<ransactionid>" + id + "</ransactionid>";
            cmd = cmd + "</command>";

            return cmd;
        }

        /// <summary>
        /// Отменить стоп-заявку
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public string CancelStopOrder(int id)
        {
            string cmd = "<command id=\"cancelstoporder\">";
            cmd = cmd + "<transactionid>" + id + "</transactionid>";
            cmd = cmd + "</command>";

            return cmd;
        } 
        #endregion

        #region Информация по лимитам
        /// <summary>
        /// Запрос позиций клиента по FORTS
        /// </summary>
        /// <param name="client"></param>
        /// <returns>Запрашивает у сервера позиции клиента на FORTS. Если не указать клиента, запрос будет выполнен по всем доступным клиентам.</returns>
        public string GetFortsPosion(string client)
        {
            string cmd = "<command id=\"get_forts_positions\">";
            cmd = cmd + "<client>" + client + "</client>";
            cmd = cmd + "</command>";

            return cmd;
        }

        /// <summary>
        /// Запрос лимитов клиента.
        /// </summary>
        /// <param name="client"></param>
        /// <returns></returns>
        public string GetClientLimtis(string client)
        {
            string cmd = "<command id=\"get_client_limits\">";
            cmd = cmd + "<client>" + client + "</client>";
            cmd = cmd + "</command>";

            return cmd;
        }

        /// <summary>
        /// Команда имеет один обязательный параметр - клиент, для которого запрашивается портфель Т+.
        /// Запрос по данной команде исполняется однократно, то есть на одну команду
        /// приходит ровно один ответ. При необходимости получить обновление данных
        /// команду нужно выполнить вновь. Ответная структура всегда приходит
        /// целиком, инкрементального обновления не предусматривается.
        /// </summary>
        /// <param name="client"></param>
        /// <returns>Результатом команды является структура portfolio_tplus</returns>
        public string GetCPortfolio(string client)
        {
            string cmd = "<command id=\"get_client_limits\">";
            cmd = cmd + "<client>" + client + "</client>";
            cmd = cmd + "</command>";

            return cmd;
        } 
        #endregion

        #region Информация по рынкам и инструментам

        /// <summary>
        /// Получить список доступных инструметнов.
        /// Результатом является структура "securities".
        /// </summary>
        public string GetSecurities()
        {
            return "<command id=\"get_securities\"/>";
        }

        /// <summary>
        /// Запросить список доступных рынков:
        /// </summary>
        /// <returns></returns>
        public string GetMarkets()
        {
            string cmd = "<command id=\"get_markets\"/>";
            return cmd;
        }

        /// <summary>
        /// Запрос на получение информации по инструменту
        /// </summary>
        /// <param name="secid">идентификатор бумаги</param>
        /// <returns>В ответ на данную команду внешнему приложению возвращается структура sec_info</returns>
        public string GetSecutitiesInfo(int secid)
        {
            string cmd = "<command id=\"get_securities_info\">";
            cmd = cmd + "<secid>" + secid + "</secid>";
            cmd = cmd + "</command>";

            return cmd;
        }

        /// <summary>
        /// Запрос на получение информации по инструменту
        /// </summary>
        /// <param name="market">внутренний код рынка</param>
        /// <param name="seccode">код инструмента</param>
        /// <returns>В ответ на данную команду внешнему приложению возвращается структура sec_info</returns>
        public string GetSecutitiesInfoBoardSeccode(string market, string seccode)
        {
            string cmd = "<command id=\"get_securities_info\">";
            cmd = cmd + "<security>";
            cmd = cmd + "<market>" + market + "</market>";
            cmd = cmd + "<seccode>" + seccode + "</seccode>";
            cmd = cmd + "</security>";
            cmd = cmd + "</command>";

            return cmd;
        } 
        #endregion
    }
}
